# -*- coding: utf-8 -*-
#
# Copyright (c) 2012, Rafael Pivato
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Rafael Pivato nor the names of its contributors
#       may be used to endorse or promote products derived from this
#       software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL RAFAEL PIVATO BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import cgi
import re
import urllib
import webapp2

from wowgae.icon import WowIconLoader


class LinkHelper(object):
    """Abstract class to represent a link to be inserted in a Web page."""

    def match(self, link):
        return None

    def wiki(self):
        """Returns the wiki code for this link, if any."""
        return ''

    def html(self):
        """Returns the html code for this link."""
        return ''


class InvalidLinkHelper(object):
    """Helps creating a link built with some invalid data."""

    def match(self, link):
        """Parses the link to a new WowLink object or None."""
        self.match_html = self.html(link)
        return self.match_html

    def html(self, link):
        return '[[%s]]' % (cgi.escape(link.strip()))


class WowLinkHelper(LinkHelper):
    """Helps creating links for WoW objects."""

    def __init__(self):
        """Creates a new link helper."""
        pattern = ur'\A\s*(?P<kind>[a-zA-Z]+)\s*=\s*(?P<key>[0-9.]+)\s*'
        pattern += ur'(?:,\s*(?P<text>.+)\s*)?\Z'
        self.re = re.compile(pattern)
        self.loader = WowIconLoader()

    def match(self, link):
        """Parses the link to a new WowLink object or None."""
        match = self.re.match(link)
        if match:
            kind, key, text = match.group('kind', 'key', 'text')
            self.match_html = self.html(kind, key, text)
            return self.match_html
        else:
            return None

    def wiki(self, kind, key, text=None):
        """Returns the Wiki representation for this WoW link."""
        if text:
            text = ',%s' % (text)
        else:
            text = ''
        wiki = u'[[%s=%s%s]]' % (kind, key, text)
        return wiki

    def html(self, kind, key, text=None):
        """Returns the HTML representation for this WoW link."""
        link = 'http://pt.wowhead.com/%s=%s' % (kind, key)
        if not text:
            text = '%s %s' % (kind.capitalize(), key)
        if kind in ['item', 'spell']:
            wow = self.loader.load_for(kind, key)
            if wow:
                text = wow.name
                icon = WowIconLoader.icon_uri(wow.icon)
            else:

                icon = WowIconLoader.unknown_icon()
            img = '<img width="15" height="15" src="%s" />' % (icon)
        else:
            img = ''
        if kind == 'item' and wow:
            quality = ' class="wg-quality-%s"' % (wow.quality)
        else:
            quality = ''
        text = cgi.escape(text)
        anchor = '<a%s href="%s">%s%s</a>' % (quality, link, img, text)
        css = ' class="wg-inline-item"'
        data = ' data-kind="%s" data-key="%s"' % (kind, key)
        span = u'<span%s%s>%s</span>' % (css, data, anchor)
        return span


class WikiLinkHelper(LinkHelper):
    """Helps creating links to Wiki pages."""

    def __init__(self):
        """Creates a new link helper."""
        pattern = ur'\A\s*(?P<page>[^/]+)\s*\Z'
        self.re = re.compile(pattern)

    def match(self, link):
        """Parses the link."""
        match = self.re.match(link)
        if match:
            page = match.group('page')
            self.match_html = self.html(page)
            return self.match_html
        else:
            return None

    def wiki(self, page):
        """Returns the Wiki representation."""
        return u'[[%s]]' % (page)

    def html(self, page):
        """Returns the HTML representation."""
        title = cgi.escape(page)
        name = page
        link = webapp2.uri_for('wiki', page=name)
        tag = u'<a href="%s">%s</a>' % (link, title)
        return tag


class EmailLinkHelper(LinkHelper):
    """Helps creating links to email addresses."""

    def __init__(self):
        """Creates a new link helper."""
        pattern = ur'\A\s*(?P<email>[-\w.]{1,50}@[-\w.]{1,50}'
        pattern += ur'(?:\.[-\w.]{1,50}){1,5})\s*\Z'
        self.re = re.compile(pattern)

    def match(self, link):
        """Parses the link."""
        match = self.re.match(link)
        if match:
            page = match.group('email')
            self.match_html = self.html(page)
            return self.match_html
        else:
            return None

    def wiki(self, email):
        """Returns the Wiki representation."""
        return u'[[%s]]' % (email)

    def html(self, email):
        """Returns the HTML representation."""
        return u'<a href="mailto:%s">%s</a>' % (email, email)


class HttpLinkHelper():
    """Helps creating links to HTTP resources."""

    def __init__(self):
        """Creates a new link helper."""
        pattern = ur'\A\s*(?P<url>http://\S+)\s*\Z'
        self.re = re.compile(pattern)

    def match(self, link):
        """Parses the link."""
        match = self.re.match(link)
        if match:
            url = match.group('url')
            self.match_html = self.html(url)
            return self.match_html
        else:
            return None

    def wiki(self, url):
        """Returns the Wiki representation."""
        return u'[[%s]]' % (url)

    def html(self, url):
        """Returns the HTML representation."""
        safe = urllib.quote(urllib.unquote_plus(url), '/.:@')
        return u'<a href="%s">%s</a>' % (safe, safe)


class YoutubeLinkHelper():
    """Helps embeding youtube videos."""

    def __init__(self):
        """Creates a new link helper."""
        pattern = ur'\A\s*https?://youtu\.be/(?P<video>[-\w_]+)'
        pattern += ur'(?:\?(?P<query>.*))?\s*\Z'
        self.re = re.compile(pattern)

    def match(self, link):
        """Parses the link."""
        match = self.re.match(link)
        if match:
            video = match.group('video')
            self.match_html = self.html(video)
            return self.match_html
        else:
            return None

    def wiki(self, video):
        """Returns the Wiki representation."""
        return u'[[http://youtu.be/%s]]' % (video)

    def html(self, video, width=313, height=200):
        """Returns the HTML representation."""
        iframe = """

        <iframe
            width="%s"
            height="%s"
            src="http://www.youtube.com/embed/%s"
            frameborder="0"
            allowfullscreen>
        </iframe>

        """
        return iframe % (width, height, video)
